<?php

namespace App\Model\Dao;

use App\Utils\CustomUtils;
use App\Concern\BaseDao;
use Hyperf\Database\Query\Builder;
use Hyperf\Database\Query\JoinClause;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Arr;
use Redis;
use App\Utils\RedisUtils;
use Hyperf\Utils\Codec\Json;

/**
 * ChannelMchConnDao
 */
class ChannelMchConnDao extends BaseDao {

    /**
     * 表名常量
     * 联表的时候通过XxxDao::TABLE获取
     */
    const TABLE = "channel_mch_conn";

    // 不支持软删除
    protected $softDelete = null;

    /**
     * 父类中通过静态函数获取表名, 因为不能通过静态常量获取, 这个函数是固定写在子类中的
     */
    public static function table (): string {
        return self::TABLE;
    }


    /**
     * 排序
     *
     * @param Builder $builder
     * @param array   $params
     *
     * @return Builder|mixed
     */
    protected function _buildOrder (Builder $builder, $params = []) {

        // 通过前端提交的参数排序
        if (Arr::exists($params, "orderBy")) {

            [$prop, $order] = $params["orderBy"];

            if (in_array($order, ["asc", "desc"])) {

                //switch ($prop) {
                //    case "yieldMonth":
                //        $builder->orderBy("main.yieldMonth", $order);
                //        break;
                //    default:
                //        break;
                //}
            }
        }

        // 如果友其他固定的排序需求, 在这里写, 例如按照时间降序
        $builder->orderBy("createTime", "desc");

        // 追加父类的排序, 父类按照ID升序, 保证排序结果唯一
        return parent::_buildOrder($builder, $params);
    }

    /**
     * 查询条件
     *
     * @param $params
     *
     * @return Builder
     */
    protected function _buildQueryString ($params) {

        // 本表一律命名为main
        $main = sprintf("%s AS main", self::TABLE);

        // 联表表名获取
        $channel = sprintf("%s AS channel", ChannelInfoDao::TABLE);

        $builder = DB::table($main);
        $builder->join($channel, 'channel.channelNo', 'main.channelNo');

        // 通过 Arr::exists 来判断是否存在该键, isset不准确

        Arr::exists($params, 'mchNo') && $builder->where('main.mchNo', $params['mchNo']);
        Arr::exists($params, 'channelNo') && $builder->where('main.channelNo', $params['channelNo']);

        Arr::exists($params, "createTimeRange") && $builder->whereBetween('main.createTime', $params['createTimeRange']);

        $builder->selectRaw(join(',', [
            'main.*',
            'channel.channelName',
            'channel.payType',
            'channel.settleCurrency',
        ]));


        return $builder;
    }

    public function getTradeLimitCostList ($params, $page, $limit) {


        $main           = sprintf('%s AS main', ChannelCollectionMchConnDao::TABLE);
        $mch            = sprintf('%s AS mch', MchInfoDao::TABLE);
        $collection     = sprintf('%s AS collection', ChannelCollectionDao::TABLE);
        $collectionConn = sprintf('%s AS collectionConn', ChannelCollectionConnDao::TABLE);
        $channel        = sprintf('%s AS channel', ChannelInfoDao::TABLE);
        $channelMchConn = sprintf('%s AS channelMchConn', ChannelMchConnDao::TABLE);


        $builder = Db::table($main);
        $builder->join($mch, 'mch.mchNo', 'main.mchNo');
        $builder->join($collection, 'collection.id', 'main.collectionId');
        $builder->join($collectionConn, 'collectionConn.collectionId', 'collection.id');
        $builder->join($channel, 'channel.channelNo', 'collectionConn.channelNo');

        $builder->leftjoinSub(Db::table($channelMchConn)->where(function (Builder $query) use ($params) {
            Arr::exists($params, 'mchNo') && $query->where('channelMchConn.mchNo', $params['mchNo']);
        }), 'channelMchConn', function (JoinClause $join) {
            $join->on('channelMchConn.channelNo', 'channel.channelNo');
        });

        $builder->selectRaw(join(',', [
            'mch.id AS mchId',
            'mch.mchNo',
            'mch.mchName',

            'main.collectionId',
            'collection.collectionName',
            'collection.payType',

            'collectionConn.sort AS channelSort',

            'channel.channelNo',
            'channel.channelName',
            'channel.settleCurrency',

            'channelMchConn.sort',
            'channelMchConn.amountMin',
            'channelMchConn.amountLimit',
            'channelMchConn.dayCountLimit',
            'channelMchConn.monthCountLimit',
            'channelMchConn.dayAmountLimit',
            'channelMchConn.monthAmountLimit',
            'channelMchConn.dayAmountThreshold',
            'channelMchConn.monthAmountThreshold',
            'channelMchConn.status',
        ]));

        // 必须有的筛选
        $builder->where('collection.status', 1);
        $builder->where('channel.status', 1);

        Arr::exists($params, 'mchNo') && $builder->where('mch.mchNo', $params['mchNo']);

        // 排序: 商户号, 支付方式, 集合ID, 商户通道优先级降序, 通道优先级降序, 通道编号
        $builder->orderBy('mch.mchNo');
        $builder->orderBy('collection.payType');
        $builder->orderBy('collection.id');
        $builder->orderBy('channelMchConn.sort', 'desc');
        $builder->orderBy('collectionConn.sort', 'desc');
        $builder->orderBy('channel.channelNo');

        $builder = $this->_buildPageLimit($builder, $page, $limit);

        $total = $builder->count();
        $list  = $builder->get()->toArray();

        return [
            'total' => $total,
            'list'  => $list,
        ];
    }


}
